# -*- coding: utf-8 -*-
# @Time : 2021/5/29 7:03
# @Author : mie
# @File : nuwa.py
# @Software: PyCharm
"""
核心修改类 NuWa（标准版）
"""
import os
from core import base
from constant import nuwaconstant as const


class NuWa(base.BaseCore):
    def start(self):
        self.rootpath = ''
        self.default_project_name = ''
        # 拼接根路径
        for pn in const.NUWA_DEFAULT_PROJECT_DIR_NAME_TUPLE:
            rootpath = os.path.join(self.targetdir, pn)
            if os.path.exists(rootpath):
                self.rootpath = rootpath
                self.default_project_name = pn
                break

        assert len(
            self.rootpath) > 0, '没有找到要修改的根目录，当前模式只允许修改顶层目录为：' + '、'.join(
                const.NUWA_DEFAULT_PROJECT_DIR_NAME_TUPLE) + '的项目'

        # 1.修改站点名称
        # self.messagehandle('正在修改标题和修站点名称...')
        # self.__alter_site_name_and_title()
        # self.messagehandle('站点名称和标题修改完成!')
        # 2.修改包名和项目名
        self.messagehandle('正在修改包名和项目名...')
        self.__alter_package_name_and_project_name(self.rootpath)
        self.messagehandle('包名和项目名修改完成!')
        # 3.修改pom.xml文件
        self.messagehandle('正在修改pom.xml...')
        self.__alter_pom_xml()
        self.messagehandle('pom.xml修改完成!')
        # 4.修改目录结构
        self.messagehandle('正在修改目录结构...')
        self.__alter_project_dir()
        self.messagehandle('目录结构修改完成!')

        if len(self.exceptions) > 0:
            self.messagehandle('\r发现有异常信息')
            self.messagehandle('-------------------\n\r')
            for e in self.exceptions:
                self.messagehandle(e)
            self.messagehandle('\r----------------------')

    def __alter_site_name_and_title(self):
        """修改站点名称和网站标题"""
        ntuple = const.NUWA_SITE_RESOURCES_PATH_TUPLE
        for item in ntuple:
            filepath = os.path.join(self.rootpath,
                                    item.replace('#', os.path.sep))
            if os.path.exists(filepath):
                try:
                    with open(filepath, 'r',
                              encoding=self.DEFAULT_ENCODING) as srcfile, open(
                                  '%s.bak' % filepath,
                                  'w',
                                  encoding=self.DEFAULT_ENCODING) as desfile:
                        for line in srcfile:
                            if const.NUWA_DEFAULT_SITE_NAME in line:
                                line = line.replace(
                                    const.NUWA_DEFAULT_SITE_NAME,
                                    self.sitename)
                            if 'nuwa后台管理系统' in line:
                                line = line.replace('nuwa后台管理系统', self.sitename)
                            if 'nuwa 后台管理系统' in line:
                                line = line.replace('nuwa 后台管理系统', self.sitename)
                            if '登录nuwa系统' in line:
                                line = line.replace('登录nuwa系统',
                                                    '登录' + self.sitename)
                            if 'nuwa系统' in line:
                                line = line.replace('nuwa系统', self.sitename)
                            if 'nuwa介绍' in line:
                                line = line.replace('nuwa介绍',
                                                    self.sitename + '介绍')
                            if 'NuWa -' in line:
                                line = line.replace('NuWa -', self.sitename)
                            desfile.write(line)
                    # 移除旧文件
                    os.remove(filepath)
                    # 重命名备份文件为新文件
                    os.rename('%s.bak' % filepath, filepath)
                except Exception as err:
                    self.exceptionhandle(
                        '修改站点名称和网站标题异常\n修改文件：{}\n异常信息：{}'.format(
                            filepath, err))

    def __alter_package_name_and_project_name(self, rootpath):
        """
        修改文件内部包名和项目名称
        修改文件的文件名以及它的依赖
        参数：
            rootpath (str): 根路径
        """
        files = os.listdir(rootpath)
        for filename in files:
            # 修改带nuwa文件的文件名
            # 剔除无关文件夹
            if '.idea' not in filename and '.svn' not in filename:
                if 'nuwa' in filename.lower() and (filename.endswith('.java') or filename.endswith(
                                '.class')):
                    new_filename = self.projectname[0].upper() + \
                               self.projectname[1:] + \
                               filename.split('Nuwa')[1]
                elif 'nuwa' in filename.lower() and not (filename.endswith('.java') or filename.endswith(
                                '.class')):
                    new_filename = self.projectname + \
                               filename.split('nuwa')[1]
                else:
                    new_filename = filename
                old_filepath = os.path.join(rootpath, filename)
                if os.path.isdir(old_filepath):
                    self.__alter_package_name_and_project_name(old_filepath)
                else:
                    # 修改nuwa文件内容
                    new_filepath = os.path.join(rootpath, new_filename)
                    os.rename(old_filepath, new_filepath)
                    if new_filename != 'pom.xml' and (new_filename.endswith('.java') or new_filename.endswith(
                            '.yml') or new_filename.endswith(
                                '.xml') or new_filename.endswith(
                                        '.vm') or new_filename.endswith(
                                            '.bat') or new_filename.endswith(
                                                '.sh')):
                        try:
                            encoding = self.get_encoding(new_filename)
                            with open(new_filepath, 'r',
                                      encoding=encoding) as srcfile, open(
                                          '%s.bak' % new_filepath,
                                          'w',
                                          encoding=encoding) as desfile:
                                self.messagehandle('正在修改：' + new_filename)
                                for line in srcfile.readlines():
                                    if const.NUWA_DEFAULT_SITE_NAME in line:
                                        line = line.replace(
                                            const.NUWA_DEFAULT_SITE_NAME,
                                            self.sitename)
                                    if const.NUWA_DEFAULT_PACKAGE_NAME in line:
                                        line = line.replace(
                                            const.NUWA_DEFAULT_PACKAGE_NAME,
                                            self.packagename)
                                    if const.NUWA_DEFAULT_CLASS_PRE_NAME in line and \
                                            (new_filename.endswith('Run.java') or new_filename.endswith('Config.java')):
                                        line = line.replace(
                                            const.NUWA_DEFAULT_CLASS_PRE_NAME,
                                            self.projectname[0].upper() + self.projectname[1:])
                                    if const.NUWA_DEFAULT_CN_PROJECT_NAME in line and new_filename.endswith('Run.java'):
                                        line = line.replace(
                                            const.NUWA_DEFAULT_CN_PROJECT_NAME,
                                            const.NUWA_DEFAULT_CN_PROJECT_NAME if self.sitename == const.NUWA_DEFAULT_SITE_NAME
                                        else self.sitename)
                                    if const.NUWA_DEFAULT_PROJECT_NAME in line and 'jdbc:mysql' not in line:
                                        line = line.replace(
                                            const.NUWA_DEFAULT_PROJECT_NAME,
                                            self.projectname)
                                    # 注意点
                                    if const.NUWA_DEFAULT_FALSE_NAME in line and self.projectname != const.NUWA_DEFAULT_PROJECT_NAME:
                                        line = line.replace(
                                            const.NUWA_DEFAULT_FALSE_NAME,
                                            self.projectname[0].upper() + self.projectname[1:])
                                    if self.configdict['config.enable'] == 'True':
                                        if new_filename.endswith('.yml'):
                                            line = self.__check_yml_config(
                                                line, new_filename)
                                    desfile.write(line)
                            # 移除旧文件
                            os.remove(new_filepath)
                            # 重命名备份文件为新文件
                            os.rename('%s.bak' % new_filepath, new_filepath)
                        except Exception as err:
                            self.exceptionhandle(
                                '修改包名和项目名称异常\n修改文件：{}\n异常信息：{}'.format(
                                    old_filepath, err))

    def __check_yml_config(self, line, filename):
        """
        检测yml配置文件

        参数:
            line (str): 行
            filename (str): 文件名
        """
        if self.configdict['config.yml']:
            if f'172.18.247.72:3306/nuwa_test' in line and \
                    filename in [f'application-{i}.yml' for i in self.configdict['config.yml'].split(',')]:
                line = self.__alert_yml_config(line, 'mysql_ip_port_name')
            if 'username: root' in line and \
                    filename in [f'application-{i}.yml' for i in self.configdict['config.yml'].split(',')]:
                line = self.__alert_yml_config(line, 'mysql_username')
            if 'password: 123456' in line and \
                    filename in [f'application-{i}.yml' for i in self.configdict['config.yml'].split(',')]:
                line = self.__alert_yml_config(line, 'mysql_password')
            if 'host: 172.18.247.72' in line and \
                    filename in [f'application-{i}.yml' for i in self.configdict['config.yml'].split(',')]:
                line = self.__alert_yml_config(line, 'redis_ip')
            if 'port: 6379' in line and \
                    filename in [f'application-{i}.yml' for i in self.configdict['config.yml'].split(',')]:
                line = self.__alert_yml_config(line, 'redis_port')
            if '- 172.18.247.72:22122' in line and \
                    filename in [f'application-{i}.yml' for i in self.configdict['config.yml'].split(',')]:
                line = self.__alert_yml_config(line, 'fdfs_tracker_list')
            if 'web-server-url: http://172.18.247.72:81/' in line and \
                    filename in [f'application-{i}.yml' for i in self.configdict['config.yml'].split(',')]:
                line = self.__alert_yml_config(line, 'fdfs_web_server_url')
            return line

    def __alert_yml_config(self, line, type_):
        """
        修改yml配置文件

        参数:
            line (str): 行
            type_ (str): 修改类型
        """
        if type_ == 'mysql_ip_port_name':
            mysql_ip = self.configdict['database.ip']
            mysql_port = self.configdict['database.port']
            mysql_name = self.configdict['database.name']
            return line.replace('172.18.247.72:3306/nuwa_test',
                                mysql_ip + ':' + mysql_port + '/' + mysql_name)
        if type_ == 'mysql_username':
            mysql_username = self.configdict['database.username']
            return line.replace('username: root',
                                'username: ' + mysql_username)
        if type_ == 'mysql_password':
            mysql_password = self.configdict['database.password']
            return line.replace('password: 123456',
                                'password: ' + mysql_password)
        if type_ == 'redis_ip':
            redis_ip = self.configdict['redis.ip']
            return line.replace('host: 172.18.247.72',
                                'host: ' + redis_ip)
        if type_ == 'redis_port':
            redis_port = self.configdict['redis.port']
            return line.replace('port: 6379',
                                'port: ' + redis_port)
        # if type_ == 'redis_password':
        #     redis_password = self.configdict['redis.password']
        #     return line.replace('password: 123456',
        #                         'password: ' + redis_password)
        if type_ == 'fdfs_tracker_list':
            fdfs_trackers = self.configdict['fdfs.trackers']
            fdfs_tracker_str = fdfs_trackers.split(',')
            fdfs_tracker_list = []
            for i in fdfs_tracker_str:
                fdfs_tracker_list.append('- ' + i)
            return line.replace('- 172.18.247.72:22122',
                                ','.join(fdfs_tracker_list))
        if type_ == 'fdfs_web_server_url':
            fdfs_web_server_url = self.configdict['fdfs.url']
            return line.replace('web-server-url: http://172.18.247.72:81/',
                                'web-server-url: ' + fdfs_web_server_url)
        return line

    def __alter_pom_xml(self):
        """修改项目pom.xml文件"""
        # 将最外层的文件夹添加到新的元组中
        ttuple = (self.default_project_name, )
        ntuple = ttuple + (const.NUWA_DEFAULT_PROJECT_NAME, ) + const.NUWA_DEFAULT_MODULE_NAME_TUPLE
        for module_name in ntuple:
            # 如果元组内元素是项目名，文件路径需要特殊处理
            if module_name == self.default_project_name:
                pom_xml_file = os.path.join(self.rootpath, const.NUWA_DEFAULT_PROJECT_NAME, 'pom.xml')
            else:
                pom_xml_file = os.path.join(self.rootpath,
                                            const.NUWA_DEFAULT_PROJECT_NAME,
                                            module_name,
                                            'pom.xml')
            if not os.path.exists(pom_xml_file):
                continue
            try:
                with open(pom_xml_file, 'r',
                          encoding=self.DEFAULT_ENCODING) as xml_file, open(
                              '%s.bak' % pom_xml_file,
                              'w',
                              encoding=self.DEFAULT_ENCODING) as target_file:
                    self.messagehandle('正在修改：' + pom_xml_file)
                    for line in xml_file:
                        # if const.NUWA_DEFAULT_GROUP_ID in line and '<groupId>' in line:
                        #     line = line.replace(const.NUWA_DEFAULT_GROUP_ID,
                        #                         self.groupid)
                        # if const.NUWA_DEFAULT_ARTIFACTID_PREFIX in line and '<artifactId>' in line:
                        #     line = line.replace(
                        #         const.NUWA_DEFAULT_ARTIFACTID_PREFIX,
                        #         self.artifactid)
                        if '<groupId>' in line:
                            line = line.replace(const.NUWA_DEFAULT_PACKAGE_NAME,
                                                self.packagename)
                        if '<artifactId>' in line or 'version>' in line:
                            line = line.replace(
                                const.NUWA_DEFAULT_PROJECT_NAME,
                                self.projectname)
                        if module_name == self.default_project_name:
                            if '<name>' in line or '<module>' in line or '<artifactId>' in line\
                                    or 'version>' in line:
                                line = line.replace(
                                    const.NUWA_DEFAULT_PROJECT_NAME,
                                    self.projectname)
                            # if 'version>' in line:
                            #     line = line.replace(
                            #         const.NUWA_DEFAULT_ARTIFACTID_PREFIX,
                            #         self.artifactid)

                            if 'description>' in line:
                                line = line.replace(
                                    const.NUWA_DEFAULT_SITE_NAME,
                                    self.sitename)
                        target_file.write(line)
                # 移除旧文件
                os.remove(pom_xml_file)
                # 重命名备份文件为新文件
                os.rename('%s.bak' % pom_xml_file, pom_xml_file)
            except Exception as err:
                self.exceptionhandle(
                    '修改项目pom.xml文件异常\n修改文件：{}\n异常信息：{}'.format(
                        pom_xml_file, err))

    # 仅仅修改目录名称
    def __alter_project_dir(self):
        old_main_dir = os.path.join(self.rootpath, const.NUWA_DEFAULT_PROJECT_NAME)
        new_main_dir = os.path.join(self.rootpath, self.projectname)
        os.rename(old_main_dir, new_main_dir)
        self.messagehandle('正在修改：' + old_main_dir)
        """修改目录名"""
        for module_name in const.NUWA_DEFAULT_MODULE_NAME_TUPLE:
            if module_name == const.NUWA_DEFAULT_MODULE_NAME_TUPLE[-1]:
                os.rename(os.path.join(self.rootpath, module_name),
                          os.path.join(self.rootpath, self.projectname + '-' +
                                       const.NUWA_DEFAULT_MODULE_NAME_TUPLE[-1].split('-')[-1]))
            else:
                if not os.path.exists(os.path.join(new_main_dir, module_name)):
                    continue
                src_main_java_dir = os.path.join(new_main_dir, module_name,
                                                 'src\\main\\java')
                # 如果没有找到源代码路径，结束本次循环
                if not os.path.exists(src_main_java_dir):
                    continue
                # 加目录
                if 'xxljob' not in module_name:
                    original_dir = os.path.join(src_main_java_dir, 'com\\jhict')
                    source_dir = os.path.join(
                        src_main_java_dir, self.packagename.replace('.', os.path.sep))
                    if os.path.exists(original_dir):
                        os.rename(original_dir, source_dir)
                if module_name != const.NUWA_DEFAULT_MODULE_NAME_TUPLE[-2]:
                    os.rename(
                        os.path.join(new_main_dir, module_name),
                        os.path.join(
                            new_main_dir,
                            self.projectname + '-' + module_name.split('-')[1]))
                else:
                    os.rename(
                        os.path.join(new_main_dir, module_name),
                        os.path.join(
                            new_main_dir,
                            self.projectname + '-' + module_name.split('-')[1]) + '-' + module_name.split('-')[-1])
                self.messagehandle('正在修改：' + module_name)
        # for extra in os.listdir(old_main_dir):
        #     shutil.move(os.path.join(old_main_dir, extra), os.path.join(new_main_dir, extra))
        self.messagehandle('正在修改：' + self.default_project_name)
        if old_main_dir != new_main_dir:
            if os.path.exists(old_main_dir):
                os.rmdir(old_main_dir)
        os.rename(self.rootpath,
                      os.path.join(self.targetdir, self.projectdirname))


